package com.bsj.pay.util.platform.wsgw.sm;

import org.bouncycastle.math.ec.*;
import java.math.*;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.crypto.*;

public class Cipher
{
    private int ct;
    private byte[] key;
    private byte keyOff;
    private ECPoint p2;
    private SM3Utils sm3c3;
    private SM3Utils sm3keybase;
    
    public Cipher() {
        this.ct = 1;
        this.key = new byte[32];
        this.keyOff = 0;
    }
    
    private void NextKey() {
        final SM3Utils sm3Utils = new SM3Utils(this.sm3keybase);
        sm3Utils.update((byte)(this.ct >> 24 & 0xFF));
        sm3Utils.update((byte)(this.ct >> 16 & 0xFF));
        sm3Utils.update((byte)(this.ct >> 8 & 0xFF));
        sm3Utils.update((byte)(this.ct & 0xFF));
        sm3Utils.doFinal(this.key, 0);
        this.keyOff = 0;
        ++this.ct;
    }
    
    private void Reset() {
        this.sm3keybase = new SM3Utils();
        this.sm3c3 = new SM3Utils();
        final byte[] byteConvert32Bytes = Util.byteConvert32Bytes(this.p2.getX().toBigInteger());
        this.sm3keybase.update(byteConvert32Bytes, 0, byteConvert32Bytes.length);
        this.sm3c3.update(byteConvert32Bytes, 0, byteConvert32Bytes.length);
        final byte[] byteConvert32Bytes2 = Util.byteConvert32Bytes(this.p2.getY().toBigInteger());
        this.sm3keybase.update(byteConvert32Bytes2, 0, byteConvert32Bytes2.length);
        this.ct = 1;
        this.NextKey();
    }
    
    public void Decrypt(final byte[] array) {
        for (int i = 0; i < array.length; ++i) {
            if (this.keyOff == this.key.length) {
                this.NextKey();
            }
            final byte b = array[i];
            final byte[] key = this.key;
            final byte keyOff = this.keyOff;
            this.keyOff = (byte)(keyOff + 1);
            array[i] = (byte)(b ^ key[keyOff]);
        }
        this.sm3c3.update(array, 0, array.length);
    }
    
    public void Dofinal(final byte[] array) {
        final byte[] byteConvert32Bytes = Util.byteConvert32Bytes(this.p2.getY().toBigInteger());
        this.sm3c3.update(byteConvert32Bytes, 0, byteConvert32Bytes.length);
        this.sm3c3.doFinal(array, 0);
        this.Reset();
    }
    
    public void Encrypt(final byte[] array) {
        this.sm3c3.update(array, 0, array.length);
        for (int i = 0; i < array.length; ++i) {
            if (this.keyOff == this.key.length) {
                this.NextKey();
            }
            final byte b = array[i];
            final byte[] key = this.key;
            final byte keyOff = this.keyOff;
            this.keyOff = (byte)(keyOff + 1);
            array[i] = (byte)(b ^ key[keyOff]);
        }
    }
    
    public void Init_dec(final BigInteger bigInteger, final ECPoint ecPoint) {
        this.p2 = ecPoint.multiply(bigInteger);
        this.Reset();
    }
    
    public ECPoint Init_enc(final SM2 sm2, final ECPoint ecPoint) {
        final AsymmetricCipherKeyPair generateKeyPair = sm2.ecc_key_pair_generator.generateKeyPair();
        final ECPrivateKeyParameters ecPrivateKeyParameters = (ECPrivateKeyParameters)generateKeyPair.getPrivate();
        final ECPublicKeyParameters ecPublicKeyParameters = (ECPublicKeyParameters)generateKeyPair.getPublic();
        final BigInteger d = ecPrivateKeyParameters.getD();
        final ECPoint q = ecPublicKeyParameters.getQ();
        this.p2 = ecPoint.multiply(d);
        this.Reset();
        return q;
    }
}
